// 基础组件类
// 提供所有组件的通用功能和接口

import React, { forwardRef, memo } from 'react';
import { cn } from '../../utils/cn';

// 基础组件属性接口
export interface BaseComponentProps {
  /** 自定义类名 */
  className?: string;
  /** 组件ID */
  id?: string;
  /** 测试ID */
  'data-testid'?: string;
  /** 是否禁用 */
  disabled?: boolean;
  /** 是否隐藏 */
  hidden?: boolean;
  /** 自定义样式 */
  style?: React.CSSProperties;
  /** 子元素 */
  children?: React.ReactNode;
  /** 点击事件 */
  onClick?: (event: React.MouseEvent) => void;
  /** 键盘事件 */
  onKeyDown?: (event: React.KeyboardEvent) => void;
  /** 焦点事件 */
  onFocus?: (event: React.FocusEvent) => void;
  /** 失焦事件 */
  onBlur?: (event: React.FocusEvent) => void;
}

// 可访问性属性接口
export interface AccessibilityProps {
  /** ARIA 标签 */
  'aria-label'?: string;
  /** ARIA 描述 */
  'aria-describedby'?: string;
  /** ARIA 展开状态 */
  'aria-expanded'?: boolean;
  /** ARIA 选中状态 */
  'aria-selected'?: boolean;
  /** ARIA 禁用状态 */
  'aria-disabled'?: boolean;
  /** Tab 索引 */
  tabIndex?: number;
  /** 角色 */
  role?: string;
}

// 完整的基础属性
export interface FullBaseProps extends BaseComponentProps, AccessibilityProps {}

// 基础组件变体
export type ComponentVariant = 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info';

// 基础组件尺寸
export type ComponentSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';

// 基础组件状态
export interface ComponentState {
  isLoading?: boolean;
  isActive?: boolean;
  isSelected?: boolean;
  isHovered?: boolean;
  isFocused?: boolean;
  isPressed?: boolean;
}

// 基础组件工厂函数
export function createBaseComponent<T extends FullBaseProps>(
  displayName: string,
  defaultProps?: Partial<T>
) {
  return forwardRef<HTMLElement, T>((props, ref) => {
    const {
      className,
      id,
      'data-testid': testId,
      disabled = false,
      hidden = false,
      style,
      children,
      onClick,
      onKeyDown,
      onFocus,
      onBlur,
      'aria-label': ariaLabel,
      'aria-describedby': ariaDescribedBy,
      'aria-expanded': ariaExpanded,
      'aria-selected': ariaSelected,
      'aria-disabled': ariaDisabled,
      tabIndex,
      role,
      ...restProps
    } = { ...defaultProps, ...props };

    // 基础样式类
    const baseClasses = cn(
      'transition-all duration-200 ease-in-out',
      'focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2',
      {
        'opacity-50 cursor-not-allowed': disabled,
        'hidden': hidden,
      },
      className
    );

    // 基础属性
    const baseProps = {
      ref,
      id,
      'data-testid': testId,
      className: baseClasses,
      style,
      onClick: disabled ? undefined : onClick,
      onKeyDown: disabled ? undefined : onKeyDown,
      onFocus: disabled ? undefined : onFocus,
      onBlur: disabled ? undefined : onBlur,
      'aria-label': ariaLabel,
      'aria-describedby': ariaDescribedBy,
      'aria-expanded': ariaExpanded,
      'aria-selected': ariaSelected,
      'aria-disabled': ariaDisabled || disabled,
      tabIndex: disabled ? -1 : tabIndex,
      role,
      ...restProps,
    };

    return { baseProps, children };
  });
}

// 高阶组件：添加性能监控
export function withPerformanceMonitoring<P extends object>(
  Component: React.ComponentType<P>,
  componentName: string
) {
  const WrappedComponent = memo((props: P) => {
    const renderStart = React.useRef<number>();
    const [renderCount, setRenderCount] = React.useState(0);

    // 记录渲染开始时间
    renderStart.current = performance.now();

    React.useEffect(() => {
      setRenderCount(prev => prev + 1);
      
      if (renderStart.current) {
        const renderTime = performance.now() - renderStart.current;
        
        // 在开发环境下记录性能数据
        if (process.env.NODE_ENV === 'development') {
          console.log(`🎯 ${componentName} render #${renderCount + 1}: ${renderTime.toFixed(2)}ms`);
          
          // 如果渲染时间过长，发出警告
          if (renderTime > 16) {
            console.warn(`⚠️ ${componentName} slow render: ${renderTime.toFixed(2)}ms`);
          }
        }
      }
    });

    return <Component {...props} />;
  });

  WrappedComponent.displayName = `withPerformanceMonitoring(${componentName})`;
  return WrappedComponent;
}

// 高阶组件：添加错误边界
export function withErrorBoundary<P extends object>(
  Component: React.ComponentType<P>,
  fallback?: React.ComponentType<{ error: Error; retry: () => void }>
) {
  const ErrorBoundary: React.FC<{ children: React.ReactNode }> = ({ children }) => {
    const [hasError, setHasError] = React.useState(false);
    const [error, setError] = React.useState<Error | null>(null);

    React.useEffect(() => {
      const handleError = (event: ErrorEvent) => {
        setHasError(true);
        setError(new Error(event.message));
      };

      window.addEventListener('error', handleError);
      return () => window.removeEventListener('error', handleError);
    }, []);

    const retry = React.useCallback(() => {
      setHasError(false);
      setError(null);
    }, []);

    if (hasError && error) {
      if (fallback) {
        const FallbackComponent = fallback;
        return <FallbackComponent error={error} retry={retry} />;
      }

      return (
        <div className="p-4 border border-red-300 rounded-md bg-red-50">
          <h3 className="text-red-800 font-medium">组件错误</h3>
          <p className="text-red-600 text-sm mt-1">{error.message}</p>
          <button
            onClick={retry}
            className="mt-2 px-3 py-1 bg-red-600 text-white rounded text-sm hover:bg-red-700"
          >
            重试
          </button>
        </div>
      );
    }

    return <>{children}</>;
  };

  const WrappedComponent: React.FC<P> = (props) => (
    <ErrorBoundary>
      <Component {...props} />
    </ErrorBoundary>
  );

  WrappedComponent.displayName = `withErrorBoundary(${Component.displayName || Component.name})`;
  return WrappedComponent;
}

// 高阶组件：添加懒加载
export function withLazyLoading<P extends object>(
  Component: React.ComponentType<P>,
  placeholder?: React.ComponentType
) {
  const LazyComponent = React.lazy(() => Promise.resolve({ default: Component }));

  const WrappedComponent: React.FC<P> = (props) => {
    const Placeholder = placeholder || (() => (
      <div className="flex items-center justify-center p-4">
        <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-primary-600"></div>
      </div>
    ));

    return (
      <React.Suspense fallback={<Placeholder />}>
        <LazyComponent {...props} />
      </React.Suspense>
    );
  };

  WrappedComponent.displayName = `withLazyLoading(${Component.displayName || Component.name})`;
  return WrappedComponent;
}

// 组合多个高阶组件
export function compose<P extends object>(
  Component: React.ComponentType<P>,
  ...hocs: Array<(comp: React.ComponentType<any>) => React.ComponentType<any>>
) {
  return hocs.reduce((acc, hoc) => hoc(acc), Component);
}

// 默认导出
export default {
  createBaseComponent,
  withPerformanceMonitoring,
  withErrorBoundary,
  withLazyLoading,
  compose,
};
